home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
lisp
/
eulisp
/
mpfeel.lha
/
MPFeel
/
Plurals
/
mp_arith.m
< prev
next >
Wrap
Text File
|
1992-07-15
|
19KB
|
808 lines
/*
* MP_Lisp
*
* Author: S.C.Merrall
*
* File: mp_arith.m
*
* Contents: int_bin_op
* float_bin_op
* bin_op
* make_integer (Don't think we need this any more)
* reduce
* scan
*
* Description: Functions to create and manipulate numeric objects
* to date, only integers.
*
*
* Change History:
*
* Date Name Comment
* -------- ---- -------
* 26:02:91 SCM Created
* 22:04:91 SCM Now use MasPar Plural Heap objects
* 15:05:91 SCM mp_int_add => plus, added make_integer
* 05:12:91 SCM added reduce and scan
*
*/
#include <mpl.h>
#include <stdio.h>
#include "p_random.h"
#include "constant.h"
#include "mp_object.h"
#include "mp_debug_off.h"
#include "mp_type.h"
#include "mp_mem_mgmt.h"
#include "mp_arith.h"
#include "mp_gc.h"
/*----------------------------------------------------------------------------*
* Function : int_bin_op
*
* Parameters : MP_PluralHeap MPPH_arg1:
* MP_PluralHeap MPPH_arg2:
* plural int bin_op_id:
* MP_PluralHeap MPPH_result:
*
* Description: Applies the given binary integer operation to the given
* arguments and returns the result in MPPPH_result;
*
* Result : int FAIL/SUCCESS
*---------------------------------------------------------------------------*/
#ifdef __STDC__
int int_bin_op( MP_PluralHeap MPPH_arg1, MP_PluralHeap MPPH_arg2,
plural int bin_op_id, MP_PluralHeap MPPH_result )
#else
int int_bin_op( MPPH_arg1, MPPH_arg2, bin_op_id, MPPH_result )
MP_PluralHeap MPPH_arg1;
MP_PluralHeap MPPH_arg2;
plural int bin_op_id;
MP_PluralHeap MPPH_result;
#endif
{
int result_status = SUCCESS;
plural int *plural integer1;
plural int *plural integer2;
plural int *plural result;
DBG_CALL("i_bin_op");
DBG_ARGS(fprintf(dbg,"MPPH_arg1=%04x, MPPH_arg2=%04x, result=%04x",MPPH_arg1,MPPH_arg2,MPPH_result));
/* Check the two plurals are non nil - new nil and t method should mean
* we don't need this
*
* if (globalor((OA_offsets(MPPH_arg1) == NIL) ||
* (OA_offsets(MPPH_arg2) == NIL))) {
*
*
*DBG_FAIL(fprintf(dbg,"FAIL: there are nil elements"));
* return FAIL;
* }
*/
if (globalor(OA_info(MPPH_arg1) != OA_info(MPPH_arg2))) {
DBG_FAIL(fprintf(dbg,"FAIL: Incompatible types"));
return FAIL;
}
if (globalor(OA_info(MPPH_arg1) != INTEGER)) {
DBG_FAIL(fprintf(dbg,"FAIL: Not all of these are inetegers"));
return FAIL;
}
/* Allocate space for answer */
if ( mp_alloc((plural int)INTEGER, (plural int) 1, MPPH_result) == FAIL) {
DBG_FAIL(fprintf(dbg,"FAIL: Unable to allocate space"));
return FAIL;
}
integer1 = (plural int *plural) OA_data(MPPH_arg1);
integer2 = (plural int *plural) OA_data(MPPH_arg2);
result = (plural int *plural) OA_data(MPPH_result);
switch (bin_op_id) {
case MP_PLUS : *result = *integer1 + *integer2; break;
case MP_DIFFERENCE : *result = *integer1 - *integer2; break;
case MP_DIVIDE : *result = *integer1 / *integer2; break;
case MP_TIMES : *result = *integer1 * *integer2; break;
case MP_REMAINDER : *result = *integer1 % *integer2; break;
default : result_status = FAIL;
}
if (result_status == FAIL) {
DBG_FAIL(fprintf(dbg,"FAIL: Unknown operation"));
return FAIL;
}
DBG_EXIT(fprintf(dbg,"SUCCESS"));
return SUCCESS;
}
/*----------------------------------------------------------------------------*
* Function : real_bin_op
*
* Parameters : MP_PluralHeap MPPH_arg1:
* MP_PluralHeap MPPH_arg2:
* plural int bin_op_id:
* MP_PluralHeap MPPH_result:
*
* Description: Applies the given binary float operation to the given
* arguments and returns the result in MPPH_result;
*
* Result : int FAIL/SUCCESS
*---------------------------------------------------------------------------*/
#ifdef __STDC__
int real_bin_op( MP_PluralHeap MPPH_arg1, MP_PluralHeap MPPH_arg2,
plural int bin_op_id, MP_PluralHeap MPPH_result )
#else
int real_bin_op( MPPH_arg1, MPPH_arg2, bin_op_id, MPPH_result )
MP_PluralHeap MPPH_arg1;
MP_PluralHeap MPPH_arg2;
plural int bin_op_id;
MP_PluralHeap MPPH_result;
#endif
{
int result_status = SUCCESS;
plural float *plural real1;
plural float *plural real2;
plural float *plural result;
DBG_CALL("float_bin_op");
DBG_ARGS(fprintf(dbg,"MPPH_arg1=%04x, MPPH_arg2=%04x, result=%04x",MPPH_arg1,MPPH_arg2,MPPH_result));
/* Check the two plurals are non nil - new system => don't need this
*
* if (globalor((OA_offsets(MPPH_arg1) == NIL) ||
* (OA_offsets(MPPH_arg2) == NIL))) {
*
*
*DBG_FAIL(fprintf(dbg,"FAIL: there are nil elements"));
* return FAIL;
* }
*/
if (globalor(OA_info(MPPH_arg1) != OA_info(MPPH_arg2))) {
DBG_FAIL(fprintf(dbg,"FAIL: Incompatible types"));
return FAIL;
}
if (globalor(OA_info(MPPH_arg1) != MP_FLOAT)) {
DBG_FAIL(fprintf(dbg,"FAIL: Not all of these are floats"));
return FAIL;
}
/* Allocate space for answer */
if ( mp_alloc((plural int)MP_FLOAT, (plural int) 1, MPPH_result) == FAIL) {
DBG_FAIL(fprintf(dbg,"FAIL: Unable to allocate space"));
return FAIL;
}
real1 = (plural float *plural) OA_data(MPPH_arg1);
real2 = (plural float *plural) OA_data(MPPH_arg2);
result = (plural float *plural) OA_data(MPPH_result);
switch (bin_op_id) {
case MP_PLUS : *result = *real1 + *real2; break;
case MP_DIFFERENCE : *result = *real1 - *real2; break;
case MP_DIVIDE : *result = *real1 / *real2; break;
case MP_TIMES : *result = *real1 * *real2; break;
case MP_REMAINDER : *result = fp_fmod(*real1,*real2); break;
default : result_status = FAIL;
}
if (result_status == FAIL) {
DBG_FAIL(fprintf(dbg,"FAIL: Unknown operation"));
return FAIL;
}
DBG_EXIT(fprintf(dbg,"SUCCESS"));
return SUCCESS;
}
/*----------------------------------------------------------------------------*
* Function : cast
*
* Parameters : MP_PluralHeap MPPH_number: MasPar Plural Heap handle on
* heap space of objects to be
* cast (numbers).
* plural int type: Types things are to be cast
* to INTEGER or MP_FLOAT
* MP_PluralHeap MPPH_result: Where the result went
*
* Description: Creates new numbers whose values are the same as the
* arguments but have been cast appropriately.
*
* Result : int: FAIL/SUCCESS
*---------------------------------------------------------------------------*/
#ifdef __STDC__
int cast( MP_PluralHeap MPPH_number,plural int type,MP_PluralHeap MPPH_result)
#else
int cast( MPPH_number, type, MPPH_result )
MP_PluralHeap MPPH_number;
plural int type;
MP_PluralHeap MPPH_result;
#endif
{
plural int integer, cast_integer;
plural float real, cast_float;
plural int initial_type;
DBG_CALL("cast");
DBG_ARGS(fprintf(dbg,"MPPH_number=????, type=????"));
integer = *(plural int *plural) OA_data(MPPH_number);
real = *(plural float *plural) OA_data(MPPH_number);
/* Check these are all numbers of one form or another */
initial_type = OA_info(MPPH_number);
if (globalor((initial_type != INTEGER) &&
(initial_type != MP_FLOAT))) {
DBG_FAIL(fprintf(dbg,"FAIL: Not all of these are numbers"));
return FAIL;
}
/* Only work on those who are changing type */
if (initial_type != type) {
/* Allocate space for new values */
if (mp_alloc(type, (plural int) 1, MPPH_result) == FAIL) {
DBG_FAIL(fprintf(dbg,"FAIL: Unable to allocate space for new numbers"));
return FAIL;
}
else {
switch(initial_type) {
case INTEGER :
*(plural float *plural) OA_data(MPPH_result) = (plural float) integer;
break;
case MP_FLOAT :
*(plural int *plural) OA_data(MPPH_result) = (plural int) real;
break;
}
}
}
else {
OA_offsets(MPPH_result) = OA_offsets(MPPH_number);
}
DBG_EXIT(fprintf(dbg,"SUCCESS"));
return SUCCESS;
}
/*----------------------------------------------------------------------------*
* Function : bin_op
*
* Parameters : MP_PluralHeap MPPH_arg1:
* MP_PluralHeap MPPH_arg2:
* plural int bin_op_id:
* MP_PluralHeap MPPH_result:
*
* Description: Applies the given binary float operation to the given
* arguments and returns the result in MPPH_result;
*
* Result : int FAIL/SUCCESS
*---------------------------------------------------------------------------*/
#ifdef __STDC__
int bin_op( MP_PluralHeap MPPH_arg1, MP_PluralHeap MPPH_arg2,
plural int bin_op_id, MP_PluralHeap MPPH_result )
#else
int bin_op( MPPH_arg1, MPPH_arg2, bin_op_id, MPPH_result )
MP_PluralHeap MPPH_arg1;
MP_PluralHeap MPPH_arg2;
plural int bin_op_id;
MP_PluralHeap MPPH_result;
#endif
{
int result_status = SUCCESS;
plural natural cast_arg1 = NIL;
MP_PluralHeap MPPH_cast_arg1 = &cast_arg1;
plural natural cast_arg2 = NIL;
MP_PluralHeap MPPH_cast_arg2 = &cast_arg2;
plural int result_type;
DBG_CALL("bin_op");
DBG_ARGS(fprintf(dbg,"MPPH_arg1=%04x, MPPH_arg2=%04x, result=%04x",MPPH_arg1,MPPH_arg2,MPPH_result));
GC_Protect(cast_arg1);
GC_Protect(cast_arg2);
if ((OA_info(MPPH_arg1) == MP_FLOAT) || (OA_info(MPPH_arg2) == MP_FLOAT))
result_type = MP_FLOAT;
else result_type = INTEGER;
if ((cast(MPPH_arg1, result_type, MPPH_cast_arg1) == FAIL) ||
(cast(MPPH_arg2, result_type, MPPH_cast_arg2) == FAIL)) {
DBG_FAIL(fprintf(dbg,"FAIL: Unable to cast some of operands"));
return FAIL;
}
if (result_type == INTEGER) {
if (int_bin_op(MPPH_cast_arg1, MPPH_cast_arg2, bin_op_id,
MPPH_result) == FAIL) {
result_status = FAIL;
}
}
else {
if (real_bin_op(MPPH_cast_arg1, MPPH_cast_arg2, bin_op_id,
MPPH_result) == FAIL) {
result_status = FAIL;
}
}
if (result_status = FAIL) {
DBG_FAIL(fprintf(dbg,"FAIL: Unable to preform operation"));
return FAIL;
}
GC_UnProtect(2);
DBG_EXIT(fprintf(dbg,"SUCCESS"));
return SUCCESS;
}
#define BOTH 0
int un_op_domains[3] = {BOTH, BOTH, MP_FLOAT};
/*----------------------------------------------------------------------------*
* Function : un_op
*
* Parameters : MP_PluralHeap MPPH_arg:
* plural int un_op_id:
* MP_PluralHeap MPPH_result:
*
* Description: Preforms the appropriate unary operator on the given values.
* Since most unary operators are floating point I have not
* bothered to split the code into sub functions.
*
* Result : int: FAIL/SUCCESS
*---------------------------------------------------------------------------*/
#ifdef __STDC__
int un_op( MP_PluralHeap MPPH_arg, plural int un_op_id,
MP_PluralHeap MPPH_result )
#else
int un_op( MPPH_arg, un_op_id, MPPH_result )
MP_PluralHeap MPPH_arg;
plural int un_op_id;
MP_PluralHeap MPPH_result;
#endif
{
int aok = TRUE;
plural int result_type;
plural int integer;
plural float real;
plural natural tmp = NIL;
MP_PluralHeap MPPH_tmp = &tmp;
DBG_CALL("un_op_id");
DBG_ARGS(fprintf(dbg,"MPPH_arg=????,un_op_id=????,MPPH_result=????"));
GC_Protect(tmp);
/* Check the plural is non nil - New system => type check sufficient
*
* if (globalor(OA_offsets(MPPH_arg) == NIL)) {
*
*DBG_FAIL(fprintf(dbg,"FAIL: there are nil elements"));
* return FAIL;
* }
*/
/* Check the plural is all numbers of some kind */
if (globalor((OA_info(MPPH_arg) != INTEGER) &&
(OA_info(MPPH_arg) != MP_FLOAT))) {
DBG_FAIL(fprintf(dbg,"FAIL: These aren't all numbers"));
return FAIL;
}
if (OA_info(MPPH_arg) == INTEGER) {
integer = *(plural int *plural) OA_data(MPPH_arg);
real = (plural float) integer;
}
else {
real = *(plural float *plural) OA_data(MPPH_arg);
integer = (plural int) real;
}
switch (un_op_id) {
case MP_NEGATE : real = -real; integer = -integer; break;
case MP_ABS : if (real < 0) {
real = -real;
integer = -integer;
}
break;
/* Hack functions for cb's neural networks */
case MP_DELTA : if (real < 0) real = -real;
real = 1 - real;
break;
case MP_SIGMA : if (real < -1.0) real = -1.0;
if (real > 1.0) real = 1.0;
break;
/* Endo of hack cb hack functions */
default : aok = FALSE;
}
if (!aok) {
DBG_FAIL(fprintf(dbg,"FAIL: Unknown unary operator id"));
return FAIL;
}
/* Determine the types of the result */
if ((OA_info(MPPH_arg) == INTEGER) &&
(un_op_domains[un_op_id-MP_UN_OP_IDS] == BOTH)) result_type = INTEGER;
else result_type = MP_FLOAT;
if (mp_alloc(result_type, (plural int) 1, MPPH_result) == FAIL) {
DBG_FAIL(fprintf(dbg,"FAIL: Unable to allocate space for the result"));
return FAIL;
}
if (result_type == INTEGER)
*(plural int *plural) OA_data(MPPH_result) = integer;
else
*(plural float *plural) OA_data(MPPH_result) = real;
GC_UnProtect(1);
DBG_EXIT(fprintf(dbg,"SUCCESS"));
return SUCCESS;
}
/*----------------------------------------------------------------------------*
* Function : rel_op
*
* Parameters : MP_PluralHeap MPPH_arg1: MasPar Plural Heap handles
* MP_PluralHeap MPPH_arg2: on the arguments.
* plural int op_id: The desired operations
* MP_PluralHeap MPPH_result: handle on result
*
* Description: Preforms the appropriate relational operator on the two
* argumnets. Which should be numbers. The numbers are all
* cast to floats and the operation preformed on these.
* The result is a nil not nil type of thing.
*
* Result : int: FAIL/SUCCESS
*---------------------------------------------------------------------------*/
#ifdef __STDC__
int rel_op( MP_PluralHeap MPPH_arg1, MP_PluralHeap MPPH_arg2,
plural int op_id, MP_PluralHeap MPPH_result )
#else
int rel_op( MPPH_arg1, MPPH_arg2, op_id, MPPH_result )
MP_PluralHeap MPPH_arg1;
MP_PluralHeap MPPH_arg2;
plural int op_id;
MP_PluralHeap MPPH_result;
#endif
{
int aok = SUCCESS;
plural float real1, real2;
plural int result;
DBG_CALL("rel_op");
DBG_ARGS(fprintf(dbg,"MPPH_arg1=????,MPPH_arg2=????,op_id=????,MPPH_result=????"));
/* Check the two plurals are non nil - New system, type check sufficient
*
* if (globalor((OA_offsets(MPPH_arg1) == NIL) ||
* (OA_offsets(MPPH_arg2) == NIL))) {
*
*DBG_FAIL(fprintf(dbg,"FAIL: there are nil elements"));
* return FAIL;
* }
*/
/* Check these are all numbers */
if (globalor((OA_info(MPPH_arg1) != INTEGER) &&
(OA_info(MPPH_arg1) != MP_FLOAT) &&
(OA_info(MPPH_arg2) != INTEGER) &&
(OA_info(MPPH_arg2) != MP_FLOAT))) {
DBG_FAIL(fprintf(dbg,"FAIL: Some of these aren't numbers"));
return FAIL;
}
if (OA_info(MPPH_arg1) == MP_FLOAT)
real1 = *(plural float *plural) OA_data(MPPH_arg1);
else
real1 = (plural float) (*(plural int *plural) OA_data(MPPH_arg1));
if (OA_info(MPPH_arg2) == MP_FLOAT)
real2 = *(plural float *plural) OA_data(MPPH_arg2);
else
real2 = (plural float) (*(plural int *plural) OA_data(MPPH_arg2));
switch (op_id) {
case MP_LT : result = (real1 < real2); break;
case MP_GT : result = (real1 > real2); break;
case MP_LE : result = (real1 <= real2); break;
case MP_GE : result = (real1 >= real2); break;
case MP_E : result = (real1 == real2); break;
default : aok = FALSE;
}
if (!aok) {
DBG_FAIL(fprintf(dbg,"FAIL: Unknown operator id"));
return FAIL;
}
if (result) OA_offsets(MPPH_result) = NOT_NIL;
else OA_offsets(MPPH_result) = NIL;
DBG_EXIT(fprintf(dbg,"SUCCESS"));
return SUCCESS;
}
/*----------------------------------------------------------------------------*
* Function : scan_op
*
* Parameters : MP_PluralHeap MPPH_arg:
* int scan_op_id:
* MP_PluralHeap MPPH_result:
*
* Description: Performs a parallel prefix scan operation
*
* Result : int: FAIL/SUCCESS
*---------------------------------------------------------------------------*/
#ifdef __STDC__
int scann_op( MP_PluralHeap MPPH_arg, int scan_op_id,
MP_PluralHeap MPPH_result )
#else
int scan_op( MPPH_arg, scan_op_id, MPPH_result )
MP_PluralHeap MPPH_arg;
int scan_op_id;
MP_PluralHeap MPPH_result;
#endif
{
int aok = TRUE;
int result_type; /* Result is all the same type */
plural int integer;
plural float real;
plural natural tmp = NIL;
MP_PluralHeap MPPH_tmp = &tmp;
DBG_CALL("un_op_id");
DBG_ARGS(fprintf(dbg,"MPPH_arg=????,un_op_id=????,MPPH_result=????"));
GC_Protect(tmp);
/* Check the plural is non nil - New System, type check sufficient
*
* if (globalor(OA_offsets(MPPH_arg) == NIL)) {
*
*DBG_FAIL(fprintf(dbg,"FAIL: there are nil elements"));
* return FAIL;
* }
*/
/* Check these are all some kind of number */
if (globalor((OA_info(MPPH_arg) != INTEGER) &&
(OA_info(MPPH_arg) != MP_FLOAT))) {
DBG_FAIL(fprintf(dbg,"FAIL: These aren't all numbers"));
return FAIL;
}
if (OA_info(MPPH_arg) == INTEGER) {
integer = *(plural int *plural) OA_data(MPPH_arg);
real = (plural float) integer;
}
else {
real = *(plural float *plural) OA_data(MPPH_arg);
integer = (plural int) real;
}
if (OA_info(MPPH_arg) == INTEGER) {
switch (scan_op_id) {
case MP_PLUS : integer = scanAdd32(integer, (plural int) 0); break;
case MP_TIMES : integer = scanMul32(integer, (plural int) 0); break;
case MP_MAX : integer = scanMax32(integer, (plural int) 0); break;
case MP_MIN : integer = scanMin32(integer, (plural int) 0); break;
default : aok = FALSE;
}
result_type = INTEGER;
}
else {
switch (scan_op_id) {
case MP_PLUS : real = scanAddf(real, (plural int) 0); break;
case MP_TIMES : real = scanMulf(real, (plural int) 0); break;
case MP_MAX : real = scanMaxf(real, (plural int) 0); break;
case MP_MIN : real = scanMinf(real, (plural int) 0); break;
default : aok = FALSE;
}
result_type = MP_FLOAT;
}
if (!aok) {
DBG_FAIL(fprintf(dbg,"FAIL: Unknown unary operator id"));
return FAIL;
}
if (mp_alloc((plural int) result_type, (plural int) 1,
MPPH_result) == FAIL) {
DBG_FAIL(fprintf(dbg,"FAIL: Unable to allocate space for the result"));
return FAIL;
}
if (result_type==INTEGER) *(plural int *plural)OA_data(MPPH_result)=integer;
else *(plural float *plural) OA_data(MPPH_result) = real;
GC_UnProtect(1);
DBG_EXIT(fprintf(dbg,"SUCCESS"));
return SUCCESS;
}
/*----------------------------------------------------------------------------*
* Function : rnd
*
* Parameters : MP_PluralHeap MPPH_result: the random numbers
*
* Description: random number per PE
*
* Result : int: FAIL, SUCCESS
*---------------------------------------------------------------------------*/
#ifdef __STDC__
int rnd( MP_PluralHeap MPPH_result )
#else
int rnd( MPPH_result )
MP_PluralHeap MPPH_result;
#endif
{
plural int *plural number;
DBG_CALL("rnd");
DBG_ARGS(fprintf(dbg,"void"));
if (mp_alloc((plural int) INTEGER, (plural int) 1,MPPH_result) == FAIL) {
DBG_FAIL(fprintf(dbg,"FAIL: Uanble to allocate space for rnd numbers"));
return FAIL;
}
number = (plural int *plural) OA_data(MPPH_result);
*number = (plural int) (fp_frandom() * 0x07000000);
DBG_EXIT(fprintf(dbg,"SUCCESS: ");DBG_PARG("","%d ",*number));
return SUCCESS;
}